﻿using Sidvall.Serialization;
using Sidvall.UI.Dialogs;
using Sidvall.UI.ViewModels;
using System;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;

namespace Sidvall.UI.Wpf.Controls
{
    public partial class SecurityControl : UserControl, IIdentityProviderDialogManagerHandler
    {
        #region Public Members

        public event System.EventHandler CloseSelected;
        public event System.EventHandler ViewTypeChanged;

        #region ViewModel

        public SecurityControlViewModel ViewModel
        {
            get
            {
                return (SecurityControlViewModel)this.DataContext;
            }
            set
            {
                this.DataContext = value;
            }
        }

        #endregion
        #region ViewType

        public SecurityControlViewType ViewType
        {
            get
            {
                return (SecurityControlViewType)this.TabControl.SelectedIndex;
            }
            set
            {
                this.TabControl.SelectedIndex = (int)value;
                this.ViewModel.ViewType = value;
                OnViewTypeChanged();
            }
        }

        #endregion

        #region InitializeContextAsync

        public async Task InitializeContextAsync(LogOnDialogContext logOnContext, LogOffDialogContext logOffContext, SecurityControlViewModelSettings viewModelSettings)
        {
            if ((logOnContext == null) && (logOffContext == null))
                throw new System.ArgumentNullException(nameof(logOnContext));

            var item = new SecurityControlViewModel();
            await item.InitializeContextAsync(logOnContext, logOffContext, viewModelSettings);
            this.ViewModel = item;
        }

        #endregion
        #region StartAsync

        public async Task StartAsync()
        {
            if (_IsStarted)
                return;
            _IsStarted = true;
            if (this.ViewModel == null)
                return;
            if (this.ViewModel.LogOffDialogContext != null)
            {
                InitializeLogOffView();
                await this.ViewModel.LogOffAsync();
            }
            if (this.ViewModel.LogOnDialogContext != null)
            {
                InitializeLogOnView();
            }
            else
            {
                OnCloseSelected();
            }
        }

        #endregion

        #endregion
        #region Private Members

        private bool _IsStarted = false;

        #region InitializeLogOffView

        private void InitializeLogOffView()
        {
            this.LogOnButton.IsDefault = false;
            this.SendCodeButton.IsDefault = false;
            this.SendEmailButton.IsDefault = false;
            this.ChangePasswordButton.IsDefault = false;
            this.ViewType = SecurityControlViewType.LogOffView;
        }

        #endregion
        #region InitializeLogOnView

        private void InitializeLogOnView()
        {
            this.LogOnButton.IsDefault = true;
            this.SendCodeButton.IsDefault = false;
            this.SendEmailButton.IsDefault = false;
            this.ChangePasswordButton.IsDefault = false;
            this.ViewType = SecurityControlViewType.LogOnView;
            Dispatcher.BeginInvoke(DispatcherPriority.Input,
                new Action(delegate ()
                {
                    if (string.IsNullOrWhiteSpace(this.ViewModel.UserName))
                    {
                        this.UserNameBox.Focus();
                        Keyboard.Focus(this.UserNameBox);
                    }
                    else
                    {
                        this.PasswordBox.Focus();
                        Keyboard.Focus(this.PasswordBox);
                    }
                }));
        }

        #endregion
        #region InitializeSubmitCodeView

        private void InitializeSubmitCodeView()
        {
            this.LogOnButton.IsDefault = false;
            this.SendCodeButton.IsDefault = true;
            this.SendEmailButton.IsDefault = false;
            this.ChangePasswordButton.IsDefault = false;
            this.ViewType = SecurityControlViewType.SubmitCodeView;
            Dispatcher.BeginInvoke(DispatcherPriority.Input,
                new Action(delegate ()
                {
                    this.CodeBox.Focus();
                    Keyboard.Focus(this.CodeBox);
                }));
        }

        #endregion
        #region InitializeChangePasswordView

        private void InitializeChangePasswordView()
        {
            this.LogOnButton.IsDefault = false;
            this.SendCodeButton.IsDefault = false;
            this.SendEmailButton.IsDefault = true;
            this.ChangePasswordButton.IsDefault = false;
            this.ViewType = SecurityControlViewType.ResetPasswordView;
            Dispatcher.BeginInvoke(DispatcherPriority.Input,
                new Action(delegate ()
                {
                    this.EmailBox.Focus();
                    Keyboard.Focus(this.EmailBox);
                }));
        }

        #endregion
        #region InitializeNewPasswordEmailView

        private void InitializeNewPasswordEmailView()
        {
            this.LogOnButton.IsDefault = false;
            this.SendCodeButton.IsDefault = false;
            this.SendEmailButton.IsDefault = false;
            this.ChangePasswordButton.IsDefault = false;
            this.ViewType = SecurityControlViewType.NewPasswordEmailView;
        }

        #endregion
        #region InitializeNewPasswordCodeView

        private void InitializeNewPasswordCodeView()
        {
            this.LogOnButton.IsDefault = false;
            this.SendCodeButton.IsDefault = false;
            this.SendEmailButton.IsDefault = false;
            this.ChangePasswordButton.IsDefault = true;
            this.ViewType = SecurityControlViewType.NewPasswordCodeView;
        }

        #endregion
        #region InitializeProxyView

        private void InitializeProxyView()
        {
            this.LogOnButton.IsDefault = false;
            this.SendCodeButton.IsDefault = false;
            this.SendEmailButton.IsDefault = false;
            this.ChangePasswordButton.IsDefault = false;
            this.ViewType = SecurityControlViewType.ProxyView;
        }

        #endregion
        #region InitializeIdentityProviderView

        private void InitializeIdentityProviderView()
        {
            this.ViewType = SecurityControlViewType.IdentityProviderView;
        }

        #endregion

        #region OnCloseSelected

        private void OnCloseSelected()
        {
            OnCloseSelected(new System.EventArgs());
        }
        private void OnCloseSelected(System.EventArgs args)
        {
            OnCloseSelected(this, args);
        }
        private void OnCloseSelected(object sender, System.EventArgs args)
        {
            if (this.CloseSelected != null)
                this.CloseSelected.Invoke(sender, args);
        }

        #endregion
        #region OnViewTypeChanged

        private void OnViewTypeChanged()
        {
            OnViewTypeChanged(new System.EventArgs());
        }
        private void OnViewTypeChanged(System.EventArgs args)
        {
            OnViewTypeChanged(this, args);
        }
        private void OnViewTypeChanged(object sender, System.EventArgs args)
        {
            if (this.ViewTypeChanged != null)
                this.ViewTypeChanged.Invoke(sender, args);
        }

        #endregion

        #region IIdentityProviderDialogManagerHandler Members

        void IIdentityProviderDialogManagerHandler.GoBack()
        {
            InitializeLogOnView();
        }
        async void IIdentityProviderDialogManagerHandler.LogOn()
        {
            await this.ViewModel.CallIdentityProviderAsync();
        }

        #endregion

        #endregion
        #region Events

        #region ChangePassword_Click

        private void ChangePassword_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            InitializeChangePasswordView();
        }

        #endregion
        #region CloseDialog_Click

        private void CloseDialog_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            switch (this.ViewType)
            {
                case SecurityControlViewType.ProxyView:
                    this.ViewModel.InitializeProxy();
                    break;
                default:
                    break;
            }
            OnCloseSelected();
        }

        #endregion
        #region GotoLogOn_Click

        private void GotoLogOn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            switch (this.ViewType)
            {
                case SecurityControlViewType.ProxyView:
                    this.ViewModel.InitializeProxy();
                    break;
                default:
                    break;
            }
            InitializeLogOnView();
        }

        #endregion
        #region LogOn_Click

        private async void LogOn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            await this.ViewModel.LogOnAsync(this.PasswordBox.Password);
            if (this.ViewModel.RequireCode)
            {
                InitializeSubmitCodeView();
            }
            else if (this.ViewModel.LogOnDialogContext.AuthorizeResponse != null)
            {
                OnCloseSelected();
            }
        }

        #endregion
        #region SendCodeButton_Click

        private async void SendCodeButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            await this.ViewModel.SendCodeAsync();
            if (this.ViewModel.LogOnDialogContext.AuthorizeResponse != null)
                OnCloseSelected();
        }

        #endregion
        #region SendEmail_Click

        private async void SendEmail_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            await this.ViewModel.SendResetPasswordEmailAsync();
            if (this.ViewModel.ViewModelSettings.SendCodeInResetPasswordEmail)
                InitializeNewPasswordCodeView();
            else
                InitializeNewPasswordEmailView();
        }

        #endregion
        #region ShowProxy_Click

        private void ShowProxy_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            InitializeProxyView();
        }

        #endregion
        #region ResetPassword_Click

        private async void ResetPassword_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var result = await this.ViewModel.ResetPasswordAsync(this.NewPasswordBox1.Password, this.NewPasswordBox2.Password);
            if (result)
                InitializeLogOnView();
        }

        #endregion
        #region IdentityProvider_Click

        private async void IdentityProvider_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            var button = sender as Button;
            if (button?.Tag == null)
                return;
            var key = button.Tag.ToString(string.Empty);
            this.ViewModel.InitializeIdentityProvider(key);
            if (this.ViewModel.IdentityProvider?.DialogManager != null)
            {
                var control = await this.ViewModel.IdentityProvider.DialogManager.GetUserControlAsync(this);
                this.IdentityProviderControl.Content = control;
                InitializeIdentityProviderView();
            }
        }

        #endregion

        #endregion
        #region Constructors

        public SecurityControl()
        {
            InitializeComponent();
        }

        #endregion
    }
}
